home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ShareWare OnLine 2
/
ShareWare OnLine Volume 2 (CMS Software)(1993).iso
/
os2
/
remin301.zip
/
REMIN300.ZIP
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-10
|
32KB
|
1,103 lines
/***************************************************************/
/* */
/* MAIN.C */
/* */
/* Main program loop, as well as miscellaneous conversion */
/* routines, etc. */
/* */
/* This file is part of REMIND. */
/* Copyright (C) 1992 by David F. Skoll. */
/* */
/***************************************************************/
#include "config.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <stdio.h>
#include <string.h>
#ifdef HAVE_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <ctype.h>
#ifdef __MSDOS__
#include <dos.h>
#endif
#ifndef __MSDOS__
#include <sys/types.h>
#ifdef SYSV
#include <time.h>
#else
#include <sys/time.h>
#endif
#endif /* ifndef __MSDOS__ */
#include "types.h"
#include "protos.h"
#include "expr.h"
#include "globals.h"
#include "err.h"
PRIVATE void DoReminders ARGS ((void));
static char TPushBuffer[TOKSIZE+1]; /* Buffer for pushing back a token. */
static char *TokenPushed = NULL;
/***************************************************************/
/***************************************************************/
/** **/
/** Main Program Loop **/
/** **/
/***************************************************************/
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int main(int argc, char *argv[])
#else
int main(argc, argv)
int argc;
char *argv[];
#endif
{
#ifdef HAVE_QUEUED
int pid;
#endif
/* The very first thing to do is to set up ErrFp to be stderr */
ErrFp = stderr;
/* Set up global vars */
ArgC = argc;
ArgV = argv;
InitRemind(argc, argv);
if(DoCalendar || DoSimpleCalendar) {
ProduceCalendar();
return 0;
}
/* Not doing a calendar. Do the regular remind loop */
DoReminders();
if (DebugFlag & DB_DUMP_VARS) DumpVarTable();
if (!Hush) {
if (DestroyOmitContexts())
Eprint("Warning: PUSH-OMIT-CONTEXT without matching POP-OMIT-CONTEXT.");
#ifdef HAVE_QUEUED
if (!Daemon && !NextMode && !NumTriggered && !NumQueued) printf("No reminders.\n");
else
if (!Daemon && !NextMode && !NumTriggered) printf("%d reminder%s queued for later today.\n",
NumQueued, (NumQueued == 1) ? "" : "s");
#else
if (!NextMode && !NumTriggered) printf("No reminders.\n");
#endif
}
/* If it's MS-DOS, reset the file access date */
#ifdef __MSDOS__
if (RealToday == JulianToday) SetAccessDate(InitialFile, RealToday);
#endif
/* If there are any background reminders queued up, handle them */
#ifdef HAVE_QUEUED
if (NumQueued || Daemon) {
if (DontFork) {
HandleQueuedReminders();
return 0;
} else {
pid = fork();
if (pid == 0) {
HandleQueuedReminders();
return 0;
}
if (pid == -1) {
fprintf(ErrFp, "Couldn't fork to do queued reminders.\n");
return 1;
}
}
}
#endif
return 0;
}
/***************************************************************/
/* */
/* DoReminders */
/* */
/* The normal case - we're not doing a calendar. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PRIVATE void DoReminders(void)
#else
static void DoReminders()
#endif
{
int r;
Token tok;
char *s;
Parser p;
FileAccessDate = GetAccessDate(InitialFile);
if (FileAccessDate < 0) {
fprintf(ErrFp, "remind: Can't access file '%s'.\n", InitialFile);
exit(1);
}
r=OpenFile(InitialFile);
if (r) {
fprintf(ErrFp, "Can't read %s: %s\n", InitialFile, ErrMsg[r]);
exit(1);
}
while(1) {
r = ReadLine();
if (r == E_EOF) return;
if (r) {
Eprint("Error reading file: %s", ErrMsg[r]);
exit(1);
}
s = FindInitialToken(&tok, CurLine);
/* Should we ignore it? */
if (NumIfs &&
tok.type != T_If &&
tok.type != T_Else &&
tok.type != T_EndIf &&
tok.type != T_IfTrig &&
ShouldIgnoreLine())
{
/*** IGNORE THE LINE ***/
}
else {
/* Create a parser to parse the line */
CreateParser(s, &p);
switch(tok.type) {
case T_Empty:
case T_Comment:
break;
case T_Rem: r=DoRem(&p); break;
case T_ErrMsg: r=DoErrMsg(&p); break;
case T_If: r=DoIf(&p); break;
case T_IfTrig: r=DoIfTrig(&p); break;
case T_Else: r=DoElse(&p); break;
case T_EndIf: r=DoEndif(&p); break;
case T_Include: r=DoInclude(&p); break;
case T_Exit: exit(99); break;
case T_Set: r=DoSet(&p); break;
case T_Fset: r=DoFset(&p); break;
case T_UnSet: r=DoUnset(&p); break;
case T_Clr: r=DoClear(&p); break;
case T_Debug: r=DoDebug(&p); break;
case T_Dumpvars: r=DoDump(&p); break;
case T_Banner: r=DoBanner(&p); break;
case T_Omit: r=DoOmit(&p);
if (r == E_PARSE_AS_REM) {
DestroyParser(&p);
CreateParser(s, &p);
r=DoRem(&p);
}
break;
case T_Pop: r=PopOmitContext(&p); break;
case T_Preserve: r=DoPreserve(&p); break;
case T_Push: r=PushOmitContext(&p); break;
case T_RemType: if (tok.val == RUN_TYPE) {
r=DoRun(&p);
break;
} else {
CreateParser(CurLine, &p);
r=DoRem(&p);
break;
}
/* If we don't recognize the command, do a REM by default */
/* Note: Since the parser hasn't been used yet, we don't */
/* need to destroy it here. */
default: CreateParser(CurLine, &p); r=DoRem(&p); break;
}
if (r && (!Hush || r != E_RUN_DISABLED)) Eprint("%s", ErrMsg[r]);
/* Destroy the parser - free up resources it may be tying up */
DestroyParser(&p);
}
}
}
/***************************************************************/
/* */
/* Julian */
/* */
/* Given day, month, year, return Julian date in days since */
/* 1 January 1990. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int Julian(int year, int month, int day)
#else
int Julian(year, month, day)
int day, month, year;
#endif
{
register int jul, iy;
if (year < BASE) return -1;
if (JulFirst == -1 || year < FirstYear) {
jul = 0;
for (iy = BASE; iy < year; iy++) jul += DaysInYear(iy);
} else {
jul = JulFirst;
for (iy = FirstYear; iy < year; iy++) jul += DaysInYear(iy);
}
return jul + MonthIndex[IsLeapYear(year)][month] + day - 1;
}
/***************************************************************/
/* */
/* FromJulian */
/* */
/* Convert a Julian date to year, month, day. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void FromJulian(int jul, int *y, int *m, int *d)
#else
void FromJulian(jul, y, m, d)
int jul;
int *y, *m, *d;
#endif
{
register int t;
if (jul >= JulFirst && JulFirst != -1) {
*y = FirstYear;
jul -= JulFirst;
} else *y = BASE;
*m = 0;
t = DaysInYear(*y);
while (jul >= t) {
jul -= t;
(*y)++;
t = DaysInYear(*y);
}
t = DaysInMonth(*m, *y);
while (jul >= t) {
jul -= t;
(*m)++;
t = DaysInMonth(*m, *y);
}
*d = jul + 1;
return;
}
/***************************************************************/
/* */
/* ParseChar */
/* */
/* Parse a character from a parse pointer. If peek is non- */
/* zero, then just peek ahead; don't advance pointer. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int ParseChar(ParsePtr p, int *err, int peek)
#else
int ParseChar(p, err, peek)
ParsePtr p;
int *err;
int peek;
#endif
{
Value val;
int r;
*err = 0;
if (TokenPushed && *TokenPushed)
if (peek) return *TokenPushed;
else return *TokenPushed++;
while(1) {
if (p->isnested) {
if (*(p->epos))
if (peek) return *(p->epos);
else return *(p->epos++);
free(p->etext); /* End of substituted expression */
p->etext = NULL;
p->epos = NULL;
p->isnested = 0;
}
if (!*(p->pos)) {
return 0;
}
if (*p->pos != BEG_OF_EXPR || !p->allownested)
if (peek) return *(p->pos);
else return *(p->pos++);
p->pos++;
r = EvalExpr(&(p->pos), &val);
if (r) {
*err = r;
DestroyParser(p);
return 0;
}
if (*p->pos != END_OF_EXPR) {
*err = E_MISS_END;
DestroyParser(p);
DestroyValue(&val);
return 0;
}
p->pos++;
r = DoCoerce(STR_TYPE, &val);
if (r) { *err = r; return 0; }
p->etext = val.v.str;
val.type = ERR_TYPE; /* So it's not accidentally destroyed! */
p->isnested = 1;
p->epos = p->etext;
}
}
/***************************************************************/
/* */
/* ParseNonSpaceChar */
/* */
/* Parse the next non-space character. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int ParseNonSpaceChar(ParsePtr p, int *err, int peek)
#else
int ParseNonSpaceChar(p, err, peek)
ParsePtr p;
int *err;
int peek;
#endif
{
int ch;
ch = ParseChar(p, err, 1);
if (*err) return 0;
while (isspace(ch)) {
ParseChar(p, err, 0); /* Guaranteed to work */
ch = ParseChar(p, err, 1);
if (*err) return 0;
}
if (!peek) ch = ParseChar(p, err, 0); /* Guaranteed to work */
return ch;
}
/***************************************************************/
/* */
/* ParseToken */
/* */
/* Parse a token delimited by whitespace. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int ParseToken(ParsePtr p, char *out)
#else
int ParseToken(p, out)
ParsePtr p;
char *out;
#endif
{
int c, err;
int len = 0;
*out = 0;
c = ParseChar(p, &err, 0);
if (err) return err;
while (c && isspace(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
if (!c) return OK;
*out++ = c;
len++;
while (c && !isspace(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
if (len < TOKSIZE && c && !isspace(c)) {
*out++ = c;
len++;
}
}
*out = 0;
return OK;
}
/***************************************************************/
/* */
/* ParseIdentifier */
/* */
/* Parse a valid identifier - ie, alpha or underscore */
/* followed by alphanum. Return E_BAD_ID if identifier is */
/* invalid. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int ParseIdentifier(ParsePtr p, char *out)
#else
int ParseIdentifier(p, out)
ParsePtr p;
char *out;
#endif
{
int c, err;
int len = 0;
*out = 0;
c = ParseChar(p, &err, 0);
if (err) return err;
while (c && isspace(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
if (!c) return E_EOLN;
if (c != '_' && !isalpha(c)) return E_BAD_ID;
*out++ = c;
*out = 0;
len++;
while (1) {
c = ParseChar(p, &err, 1);
if (err) return err;
if (c != '_' && !isalnum(c)) return OK;
if (len < TOKSIZE) {
c = ParseChar(p, &err, 0); /* Guaranteed to work */
*out++ = c;
*out = 0;
len++;
}
}
}
/***************************************************************/
/* */
/* EvaluateExpr */
/* */
/* We are expecting an expression here. Evaluate it and */
/* return the value. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int EvaluateExpr(ParsePtr p, Value *v)
#else
int EvaluateExpr(p, v)
ParsePtr p;
Value *v;
#endif
{
int bracketed = 0;
int r;
if (p->isnested) return E_PARSE_ERR; /* Can't nest expressions */
while (isspace(*p->pos)) (p->pos)++;
if (!p->pos) return E_PARSE_ERR; /* Missing expression */
if (*p->pos == BEG_OF_EXPR) {
(p->pos)++;
bracketed = 1;
}
r = EvalExpr(&(p->pos), v);
if (r) return r;
if (bracketed) {
if (*p->pos != END_OF_EXPR) return E_MISS_END;
(p->pos)++;
}
return OK;
}
/***************************************************************/
/* */
/* Eprint - print an error message. */
/* */
/***************************************************************/
#ifdef HAVE_STDARG
#ifdef HAVE_PROTOS
PUBLIC void Eprint(const char *fmt, ...)
#else
void Eprint(fmt)
char *fmt;
#endif
#else
/*VARARGS0*/
void Eprint(va_alist)
va_dcl
#endif
{
va_list argptr;
#ifndef HAVE_STDARG
char *fmt;
#endif
/* Check if more than one error msg. from this line */
if (!FreshLine && !ShowAllErrors) return;
if (FreshLine) {
FreshLine = 0;
(void) fprintf(ErrFp, "%s(%d): ", FileName, LineNo);
if (DebugFlag & DB_PRTLINE) OutputLine(ErrFp);
} else fprintf(ErrFp, " ");
#ifdef HAVE_STDARG
va_start(argptr, fmt);
#else
va_start(argptr);
fmt = va_arg(argptr, char *);
#endif
(void) vfprintf(ErrFp, fmt, argptr);
(void) fputc('\n', ErrFp);
#ifndef HAVE_STDARG
va_end(argptr)
#endif
return;
}
/***************************************************************/
/* */
/* OutputLine */
/* */
/* Output a line from memory buffer to a file pointer. This */
/* simply involves escaping newlines. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void OutputLine(FILE *fp)
#else
void OutputLine(fp)
FILE *fp;
#endif
{
register char *s = CurLine;
while (*s) {
if (*s == '\n') putc('\\', fp);
putc(*s, fp);
s++;
}
if (*(s-1) != '\n') putc('\n', fp);
}
/***************************************************************/
/* */
/* CreateParser */
/* */
/* Create a parser given a string buffer */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void CreateParser(char *s, ParsePtr p)
#else
void CreateParser(s, p)
char *s;
ParsePtr p;
#endif
{
p->text = s;
p->pos = s;
p->isnested = 0;
p->epos = NULL;
p->etext = NULL;
p->allownested = 1;
TokenPushed = NULL;
}
/***************************************************************/
/* */
/* DestroyParser */
/* */
/* Destroy a parser, freeing up resources used. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void DestroyParser(ParsePtr p)
#else
void DestroyParser(p)
ParsePtr p;
#endif
{
if (p->isnested && p->etext) {
free(p->etext);
p->etext = NULL;
p->isnested = 0;
}
}
/***************************************************************/
/* */
/* PushToken - one level of token pushback. This is */
/* GLOBAL, not on a per-parser basis. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC void PushToken(const char *tok)
#else
void PushToken(tok)
char *tok;
#endif
{
TokenPushed = TPushBuffer;
strcpy(TPushBuffer, tok);
strcat(TPushBuffer, " "); /* Separate the pushed token from the next
token */
}
/***************************************************************/
/* */
/* SystemTime */
/* */
/* Return the system time in seconds past midnight */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC long SystemTime(void)
#else
long SystemTime()
#endif
{
#ifdef __MSDOS__
#ifdef __TURBOC__
/* Get time in Turbo C */
struct time t;
gettime(&t);
return (long) t.ti_hour * 3600L + (long) t.ti_min * 60L +
(long) t.ti_sec;
#else
/* Get time in Microsoft C */
struct dostime_t tloc;
_dos_gettime(&tloc);
return (long) tloc.hour * 3600L + (long) tloc.minute * 60L +
(long) tloc.second;
#endif
#else
/* Get time in Unix */
time_t tloc;
struct tm *t;
(void) time(&tloc);
t = localtime(&tloc);
return (long) t->tm_hour * 3600L + (long) t->tm_min * 60L +
(long) t->tm_sec;
#endif
}
/***************************************************************/
/* */
/* SystemDate */
/* */
/* Obtains today's date. Returns Julian date or -1 for */
/* failure. (Failure happens if sys date is before BASE */
/* year.) */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int SystemDate(int *y, int *m, int *d)
#else
int SystemDate(y, m, d)
int *d;
int *m;
int *y;
#endif
{
#ifdef __MSDOS__
#ifdef __TURBOC__
/* Get today's date in Turbo C */
struct date da;
getdate(&da);
*y = da.da_year;
*m = da.da_mon - 1;
*d = da.da_day;
#else
/* Get today's date in Microsoft C */
struct dosdate_t buf;
_dos_getdate(&buf);
*d = buf.day;
*m = buf.month - 1;
*y = buf.year;
#endif
#else
/* Get today's date in UNIX */
time_t tloc;
struct tm *t;
(void) time(&tloc);
t = localtime(&tloc);
*d = t->tm_mday;
*m = t->tm_mon;
*y = t->tm_year + 1900;
#endif
return Julian(*y, *m, *d);
}
/***************************************************************/
/* */
/* DoIf - handle the IF command. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoIf(ParsePtr p)
#else
int DoIf(p)
ParsePtr p;
#endif
{
Value v;
int r;
unsigned syndrome;
if (NumIfs >= IF_NEST) return E_NESTED_IF;
if (ShouldIgnoreLine()) syndrome = IF_TRUE | BEFORE_ELSE;
else {
if (r = EvaluateExpr(p, &v)) {
syndrome = IF_TRUE | BEFORE_ELSE;
Eprint("%s", ErrMsg[r]);
} else
if ( (v.type != STR_TYPE && v.v.val) ||
(v.type == STR_TYPE && strcmp(v.v.str, "")) )
syndrome = IF_TRUE | BEFORE_ELSE;
else
syndrome = IF_FALSE | BEFORE_ELSE;
}
NumIfs++;
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
IfFlags |= syndrome << (2 * NumIfs - 2);
if (ShouldIgnoreLine()) return OK;
return VerifyEoln(p);
}
/***************************************************************/
/* */
/* DoElse - handle the ELSE command. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoElse(ParsePtr p)
#else
int DoElse(p)
ParsePtr p;
#endif
{
unsigned syndrome;
if (!NumIfs) return E_ELSE_NO_IF;
syndrome = IfFlags >> (2 * NumIfs - 2);
if ((syndrome & IF_ELSE_MASK) == AFTER_ELSE) return E_ELSE_NO_IF;
IfFlags |= AFTER_ELSE << (2 * NumIfs - 2);
return VerifyEoln(p);
}
/***************************************************************/
/* */
/* DoEndif - handle the Endif command. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoEndif(ParsePtr p)
#else
int DoEndif(p)
ParsePtr p;
#endif
{
if (!NumIfs) return E_ENDIF_NO_IF;
NumIfs--;
return VerifyEoln(p);
}
/***************************************************************/
/* */
/* DoIfTrig */
/* */
/* Handle the IFTRIG command. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoIfTrig(ParsePtr p)
#else
int DoIfTrig(p)
ParsePtr p;
#endif
{
int r;
unsigned syndrome;
Trigger trig;
TimeTrig tim;
int jul;
if (NumIfs >= IF_NEST) return E_NESTED_IF;
if (ShouldIgnoreLine()) syndrome = IF_TRUE | BEFORE_ELSE;
else {
if (r=ParseRem(p, &trig, &tim)) return r;
if (trig.typ != NO_TYPE) return E_PARSE_ERR;
jul = ComputeTrigger(JulianToday, &trig, &r);
if (r) syndrome = IF_TRUE | BEFORE_ELSE;
else {
if (ShouldTriggerReminder(&trig, &tim, jul))
syndrome = IF_TRUE | BEFORE_ELSE;
else
syndrome = IF_FALSE | BEFORE_ELSE;
}
}
NumIfs++;
IfFlags &= ~(IF_MASK << (2*NumIfs - 2));
IfFlags |= syndrome << (2 * NumIfs - 2);
return OK;
}
/***************************************************************/
/* */
/* ShouldIgnoreLine - given the current state of the IF */
/* stack, should we ignore the current line? */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int ShouldIgnoreLine(void)
#else
int ShouldIgnoreLine()
#endif
{
register int i, syndrome;
/* Algorithm - go from outer to inner, and if any should be ignored, then
ignore the whole. */
for (i=0; i<NumIfs; i++) {
syndrome = (IfFlags >> (i*2)) & IF_MASK;
if (syndrome == IF_TRUE+AFTER_ELSE ||
syndrome == IF_FALSE+BEFORE_ELSE) return 1;
}
return 0;
}
/***************************************************************/
/* */
/* VerifyEoln */
/* */
/* Verify that current line contains no more tokens. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int VerifyEoln(ParsePtr p)
#else
int VerifyEoln(p)
ParsePtr p;
#endif
{
int r;
if (r = ParseToken(p, TokBuffer)) return r;
if (*TokBuffer && (*TokBuffer != '#') && (*TokBuffer != ';')) {
Eprint("Expecting end-of-line, found '%s'", TokBuffer);
return E_EXTRANEOUS_TOKEN;
}
return OK;
}
/***************************************************************/
/* */
/* DoDebug */
/* */
/* Set the debug options under program control. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoDebug(ParsePtr p)
#else
int DoDebug(p)
ParsePtr p;
#endif
{
int err;
int ch;
int val=1;
while(1) {
ch = ParseChar(p, &err, 0);
if (err) return err;
switch(ch) {
case '#':
case ';':
case 0:
return OK;
case ' ':
case '\t':
break;
case '+':
val = 1;
break;
case '-':
val = 0;
break;
case 'e':
case 'E':
if (val) DebugFlag |= DB_ECHO_LINE;
else DebugFlag &= ~DB_ECHO_LINE;
break;
case 'x':
case 'X':
if (val) DebugFlag |= DB_PRTEXPR;
else DebugFlag &= ~DB_PRTEXPR;
break;
case 't':
case 'T':
if (val) DebugFlag |= DB_PRTTRIG;
else DebugFlag &= ~DB_PRTTRIG;
break;
case 'v':
case 'V':
if (val) DebugFlag |= DB_DUMP_VARS;
else DebugFlag &= ~DB_DUMP_VARS;
break;
case 'l':
case 'L':
if (val) DebugFlag |= DB_PRTLINE;
else DebugFlag &= ~DB_PRTLINE;
break;
}
}
}
/***************************************************************/
/* */
/* DoBanner */
/* */
/* Set the banner to be printed just before the first */
/* reminder is issued. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoBanner(ParsePtr p)
#else
int DoBanner(p)
ParsePtr p;
#endif
{
int err;
int c;
char buf[LINELEN]; /* So we don't mess up the banner if an error occurs */
char *s;
c = ParseChar(p, &err, 0);
if (err) return err;
while (isspace(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
if (!c) return E_EOLN;
s = buf;
while(c) {
*s++ = c;
c = ParseChar(p, &err, 0);
if (err) return err;
}
*s++ = 0;
strcpy(Banner, buf);
return OK;
}
/***************************************************************/
/* */
/* DoRun */
/* */
/* Enable or disable the RUN command under program control */
/* */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoRun(ParsePtr p)
#else
int DoRun(p)
ParsePtr p;
#endif
{
int r;
if (!TopLevel())
return OK; /* Silently ignore RUN command in included file */
if (r=ParseToken(p, TokBuffer)) return r;
if (StriEq(TokBuffer, "ON"))
RunDisabled &= ~RUN_SCRIPT;
else if (StriEq(TokBuffer, "OFF"))
RunDisabled |= RUN_SCRIPT;
else return E_PARSE_ERR;
return VerifyEoln(p);
}
/***************************************************************/
/* */
/* DoErrMsg */
/* */
/* Issue an error message under program control. */
/* */
/***************************************************************/
#ifdef HAVE_PROTOS
PUBLIC int DoErrMsg(ParsePtr p)
#else
int DoErrMsg(p)
ParsePtr p;
#endif
{
TimeTrig tt;
Trigger t;
int r;
char *s;
t.typ = MSG_TYPE;
tt.ttime = SystemTime() / 60;
if (r=DoSubst(p, SubstBuffer, &t, &tt, JulianToday, NORMAL_MODE)) return r;
s = SubstBuffer;
while (isspace(*s)) s++;
fprintf(ErrFp, "%s\n", s);
return OK;
}